package com.fjwt.gz.core.utils;

import cn.hutool.core.map.MapUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.fjwt.gz.core.cache.RedisUtil;
import com.fjwt.gz.core.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author Hmw
 * @version 1.0
 * @date 2022-09-17 16:49
 */
@Slf4j
public class WxUtil {

    // 郑州福利社（配置参数）
//    private static final String APPID = "wx554f86dfa21d0373";//  wxdb0d7deb4427d9ed
//    private static final String APP_SECRET_KEY = "1855e4e0d6da274350549ceb812acc80"; //    fba44a28bb000ac1256a4d62f349c84f

    // todo 待调整
//    public static Map<String, Object> getWxSmallOpenId(String code) {
//        CloseableHttpClient httpClient = HttpClients.custom()
//                .disableContentCompression().disableAutomaticRetries().build();
//        CloseableHttpResponse response = null;
//        String appid = APPID; // "wxdb0d7deb4427d9ed";
//        String appSecretKey = APP_SECRET_KEY; //"fba44a28bb000ac1256a4d62f349c84f";
//        HttpGet httpGet = new HttpGet("https://api.weixin.qq.com/sns/jscode2session?appid=" + appid + "&secret=" + appSecretKey + "&js_code=" + code + "&grant_type=authorization_code");
//        httpGet.addHeader("Accept", "application/json;charset=utf-8");
//        String res = "";
//        try {
//            response = httpClient.execute(httpGet);
//            HttpEntity entity = response.getEntity();
//            res = EntityUtils.toString(entity, "UTF-8");
//        } catch (IOException e) {
//            e.printStackTrace();
//        } finally {
//            try {
//                httpClient.close();
//            } catch (IOException e) {
//                log.error("链接流关闭失败");
//                e.printStackTrace();
//            }
//        }
//
//        log.info("微信接口返回结果：{}", res);
//        Map<String, Object> mapRes = JSONUtil.parseObj(res);
//
//        return mapRes;
//    }

    /**
     * 获取用户地域小程序的openid
     * @param code
     * @param appid
     * @param appSecretKey
     * @return
     */
    public static Map<String, Object> getWxPlaceOpenId(String code,String appid,String appSecretKey) {
        CloseableHttpClient httpClient = HttpClients.custom()
                .disableContentCompression().disableAutomaticRetries().build();
        CloseableHttpResponse response = null;
        String reqUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appid + "&secret=" + appSecretKey + "&js_code=" + code + "&grant_type=authorization_code";
        log.info("请求路径：{}",reqUrl);
        HttpGet httpGet = new HttpGet(reqUrl);
        httpGet.addHeader("Accept", "application/json;charset=utf-8");
        String res = "";
        try {
            response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            res = EntityUtils.toString(entity, "UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                log.error("链接流关闭失败");
                e.printStackTrace();
            }
        }

        log.info("微信接口获取用户地域小程序返回结果：{}", res);
        Map<String, Object> mapRes = JSONUtil.parseObj(res);

        return mapRes;
    }

    // 微信获取认证token
    public static String getAccessToken(String appid,String appSecretKey) {

        String value = RedisUtil.getString("ACCESSTOKEN"+":"+appid);


        if (value == null || value.equals("")) {
            long sTime = System.currentTimeMillis() / 1000 ;
            CloseableHttpClient httpClient = HttpClients.custom()
                    .disableContentCompression().disableAutomaticRetries().build();
            CloseableHttpResponse response = null;

            HttpGet httpGet = new HttpGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + appSecretKey);
            httpGet.addHeader("Accept", "application/json;charset=utf-8");
            String res = "";
            try {
                response = httpClient.execute(httpGet);
                HttpEntity entity = response.getEntity();
                res = EntityUtils.toString(entity, "UTF-8");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    log.error("链接流关闭失败");
                    e.printStackTrace();
                }
            }
            Long eTime = System.currentTimeMillis() / 1000 ;
            log.info("获取小程序token调用凭证开始时间：{},结束时间：{},接口调用时间：{}",sTime,eTime,eTime-sTime);
            log.info("微信接口获取access_token返回结果：{}", res);
            Map<String, Object> mapRes = JSONUtil.parseObj(res);

            if (!mapRes.containsKey("access_token")) {
                return "";
            }
            Integer expires_in = MapUtil.getInt(mapRes, "expires_in");
            String accessToken = MapUtils.getString(mapRes, "access_token");
            RedisUtil.setString("ACCESSTOKEN"+":"+appid,accessToken,  expires_in-(eTime-sTime));
            value = accessToken;
        }
        return value;
    }

    public static String getPhoneNumber(String code,String appId,String appSecretKey) {

        Map<String, Object> parms = new HashMap<>();
        parms.put("code", code);
        String accessToken = getAccessToken(appId, appSecretKey);
        if(StringUtils.isEmpty(accessToken)){
            accessToken = getAccessToken(appId, appSecretKey);
        }
        String result= HttpUtil.createPost("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken).contentType("application/json")
                .body(JSON.toJSONString(parms)).execute().body();


        Map<String, Object> mapRes = JSONUtil.parseObj(result);
        Integer errcode = MapUtils.getInteger(mapRes, "errcode");
        if (0 != errcode){
            //删除redis中的ACCESSTOKEN缓存
            RedisUtil.del("ACCESSTOKEN"+":"+appId);
            throw  new BizException("系统繁忙，请稍后重试");
        }

        Map<String, Object> maps = JSONUtil.parseObj(MapUtils.getString(mapRes, "phone_info"));



        log.info("微信接口获取手机号返回结果：{}", result);
        return MapUtils.getString(maps, "phoneNumber");
    }


    /**
     * 生成二维码图片
     * @return
     */
    public static byte[] getUnlimitedQRCode(JSONObject json,String appid,String appSecretKey){
        String accessToken = getAccessToken(appid, appSecretKey);
        if(StringUtils.isEmpty(accessToken)){
           accessToken =  getAccessToken(appid,appSecretKey);
        }
        HttpResponse execute = HttpUtil.createPost("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken).contentType("application/json")
                .body(JSON.toJSONString(json)).execute();
        return execute.bodyBytes();
    }

    /**
     * 生成小程序活动授权码
     * @param activityId
     * @param appId
     * @return
     */
    public static String getUnlimitedQRCode(Long activityId, String appId, String appSecret, Long outTime, boolean isFormalCode) {
        String REDIS_KEY = "QRACTIVITY:" + activityId;
        String qrActivity = RedisUtil.getString(REDIS_KEY + activityId);
        log.info("获取活动的二维码：{}",qrActivity);
        if(StringUtils.isEmpty(qrActivity)){
            JSONObject json = new JSONObject();
            json.put("scene","acteType=issue&activityId=" + activityId);
            json.put("page","pages/welcome/index");
            if (!isFormalCode){
                json.put("env_version","trial");
            }
//            json.put("check_path",false);
            byte[] bytes = WxUtil.getUnlimitedQRCode(json, appId, appSecret);
            String code =  Base64.encodeBase64String(bytes);
            log.info("返回小程序码:{}",code);
            log.info("生成小程序二维码过期时间：{}", outTime / 1000);
            RedisUtil.setString(REDIS_KEY, code, outTime, TimeUnit.MILLISECONDS);
            return code;
        }
        return qrActivity;
    }

    /**
     * 微信推送消息通知
     * @param jsonObject
     * @throws Exception
     */
    public static void sendWxGzhNotice(JSONObject jsonObject) throws Exception{
        log.info("微信推送消息通知:{}",JSONUtil.toJsonStr(jsonObject));
        JSONObject json = new JSONObject();
        JSONObject data = new JSONObject();
        data.put("openid",jsonObject.getString("openid"));
        data.put("platform_id","171");
        data.put("template_id","hDx5Iy6fmaf8gsq4Hdo5lPeWC7HHNsR0tWke6BE5D5U");
        JSONObject content = new JSONObject();
        content.put("thing15",jsonObject.getString("thing15"));
        content.put("thing2",jsonObject.getString("thing2"));
        content.put("thing5",jsonObject.getString("thing5"));
        content.put("time",jsonObject.getString("time"));
        data.put("template_content",content.toString());
        JSONObject msg = new JSONObject();
        msg.put("appid",jsonObject.getString("appid"));
        msg.put("pagepath",jsonObject.getString("pagepath"));
        msg.put("activity_title",jsonObject.getString("thing2"));
        msg.put("title",jsonObject.getString("thing15"));
        msg.put("reply_title",jsonObject.getString("thing5"));
        msg.put("time",jsonObject.getString("time"));
        data.put("msg",msg);
        log.info("微信推送消息加密前参数：{}", JSON.toJSONString(data));
        json.put("data", EncAesUtils.encode(JSON.toJSONString(data),"lmTVCIfGzwKBgQCH"));
        json.put("action","wechat.service.WxNoticeService.sendWxGzhNotice");
        JSONObject object = new JSONObject();
        object.put("data",json);
        object.put("service","ip");
        log.info("微信推送消息通知,reqJson:{} ",JSON.toJSONString(object));

        String url = "https://zzfls.post183.net/webApi.php";
        HttpResponse execute = HttpUtil.createPost(url).contentType("application/json").body(JSON.toJSONString(object)).execute();
        log.info("微信推送消息通知,execute:{}",JSONUtil.toJsonStr(execute));
        log.info("微信推送消息通知,body:{}",execute.body());
    }

}
